package main

import (
	"fmt"
	"html/template"
	"net/url"
	"path/filepath"

	"github.com/gofiber/fiber/v2"
)

// SetupRoutes 注册所有路由
func SetupRoutes(app *fiber.App, fileService *FileService) {
	app.Post("/delete-folder", func(c *fiber.Ctx) error {
		path := c.FormValue("path")
		if path == "" {
			return c.Status(400).SendString("缺少 path 参数")
		}
		dir := c.FormValue("dir")
		err := fileService.DeleteFolder(path)
		if err != nil {
			return c.Status(500).SendString(fmt.Sprintf("删除文件夹失败: %v", err))
		}
		// 删除后重定向回当前目录
		if dir != "" {
			return c.Redirect("/?name=" + url.QueryEscape(dir))
		}
		return c.Redirect("/")
	})
	app.Get("/", func(c *fiber.Ctx) error {
		rel := c.Query("name", "")
		html := `<html><head><meta charset="utf-8"></head><body><h1>文件列表</h1>
				  <form action="/add" method="post" enctype="multipart/form-data" style="margin-bottom:10px;">
					  <input type="file" name="file">
					  <input type="hidden" name="dir" value="` + template.HTMLEscapeString(rel) + `">
					  <input type="submit" value="上传文件">
				  </form>
				  <form action="/add-folder" method="post" style="margin-bottom:20px;">
					  <input type="text" name="folder" placeholder="新建文件夹名" required>
					  <input type="hidden" name="dir" value="` + template.HTMLEscapeString(rel) + `">
					  <input type="submit" value="新建文件夹">
				  </form>`
		list, err := renderDirService(fileService, rel)
		if err != nil {
			return c.Status(500).SendString(fmt.Sprintf("读取目录内容失败: %v", err))
		}
		html += list
		html += "</body></html>"
		c.Set("Content-Type", "text/html; charset=utf-8")
		return c.SendString(html)
	})

	app.Post("/add-folder", func(c *fiber.Ctx) error {
		dir := c.FormValue("dir")
		folder := c.FormValue("folder")
		if folder == "" {
			return c.Status(400).SendString("缺少文件夹名")
		}
		var folderPath string
		if dir != "" {
			folderPath = filepath.ToSlash(filepath.Join(dir, folder))
		} else {
			folderPath = folder
		}
		err := fileService.AddFolder(folderPath)
		if err != nil {
			return c.Status(500).SendString(fmt.Sprintf("新建文件夹失败: %v", err))
		}
		// 新建后重定向回当前目录
		if dir != "" {
			return c.Redirect("/?name=" + url.QueryEscape(dir))
		}
		return c.Redirect("/")
	})

	app.Get("/file", func(c *fiber.Ctx) error {
		name := c.Query("name")
		if name == "" {
			return c.Status(400).SendString("文件名未提供")
		}
		cleanName := filepath.Clean(name)
		absPath, err := fileService.GetFile(cleanName)
		if err == nil {
			return c.SendFile(absPath)
		}
		html := "<html><head><meta charset=\"utf-8\"></head><body><h1>文件列表</h1>"
		list, err := renderDirService(fileService, cleanName)
		if err != nil {
			return c.Status(500).SendString(fmt.Sprintf("读取目录内容失败: %v", err))
		}
		html += list
		html += "</body></html>"
		c.Set("Content-Type", "text/html; charset=utf-8")
		return c.SendString(html)
	})

	app.Post("/add", func(c *fiber.Ctx) error {
		dir := c.FormValue("dir")
		fileHeader, err := c.FormFile("file")
		if err != nil {
			return c.Status(400).SendString("未选择文件")
		}
		file, err := fileHeader.Open()
		if err != nil {
			return c.Status(500).SendString("无法打开上传的文件")
		}
		defer file.Close()
		data := make([]byte, fileHeader.Size)
		_, err = file.Read(data)
		if err != nil {
			return c.Status(500).SendString("读取文件内容失败")
		}
		var savePath string
		if dir != "" {
			savePath = filepath.ToSlash(filepath.Join(dir, fileHeader.Filename))
		} else {
			savePath = fileHeader.Filename
		}
		err = fileService.AddFile(savePath, data)
		if err != nil {
			return c.Status(500).SendString(fmt.Sprintf("添加文件失败: %v", err))
		}
		// 上传后重定向回当前目录
		if dir != "" {
			return c.Redirect("/?name=" + url.QueryEscape(dir))
		}
		return c.Redirect("/")
	})

	app.Post("/delete", func(c *fiber.Ctx) error {
		path := c.FormValue("path")
		if path == "" {
			return c.Status(400).SendString("缺少 path 参数")
		}
		dir := c.FormValue("dir")
		err := fileService.DeleteFile(path)
		if err != nil {
			return c.Status(500).SendString(fmt.Sprintf("删除文件失败: %v", err))
		}
		// 删除后重定向回当前目录
		if dir != "" {
			return c.Redirect("/?name=" + url.QueryEscape(dir))
		}
		return c.Redirect("/")
	})
}

// 渲染目录为 HTML 列表
func renderDirService(s *FileService, rel string) (string, error) {
	dirEntries, err := s.ListDir(rel)
	if err != nil {
		return "", err
	}
	html := "<ul>"
	if rel != "" {
		parent := filepath.Dir(rel)
		if parent == "." {
			parent = ""
		}
		parentLink := url.QueryEscape(filepath.ToSlash(parent))
		if parentLink == "" {
			html += `<li><a href="/"><b>..</b></a></li>`
		} else {
			html += fmt.Sprintf(`<li><a href="/file?name=%s"><b>..</b></a></li>`, parentLink)
		}
	}
	for _, entry := range dirEntries {
		name := entry.Name()
		var relPath string
		if rel == "" {
			relPath = name
		} else {
			relPath = filepath.ToSlash(filepath.Join(rel, name))
		}
		link := url.QueryEscape(relPath)
		// 获取文件/文件夹信息
		info, _ := s.GetFileInfo(relPath)
		var infoStr string
		if info != nil {
			if info.IsDir() {
				infoStr = fmt.Sprintf("<span style='color:#888;font-size:12px;'>(文件夹, 修改:%s)</span>", info.ModTime().Format("2006-01-02 15:04:05"))
			} else {
				infoStr = fmt.Sprintf("<span style='color:#888;font-size:12px;'>(%.2fMb, 修改:%s)</span>", float64(info.Size())/1024/1024, info.ModTime().Format("2006-01-02 15:04:05"))
			}
		}
		if entry.IsDir() {
			html += fmt.Sprintf(`
				   <li>
					   <a href="/?name=%s">%s</a> %s
					   <form action="/delete-folder" method="post" style="display:inline;" onsubmit="return confirm('确定要删除该文件夹及其所有内容吗？');">
						   <input type="hidden" name="path" value="%s">
						   <input type="hidden" name="dir" value="%s">
						   <input type="submit" value="删除文件夹" style="margin-left:10px;">
					   </form>
				   </li>
			   `, link, template.HTMLEscapeString(name), infoStr, template.HTMLEscapeString(relPath), template.HTMLEscapeString(rel))
		} else {
			html += fmt.Sprintf(`
					  <li>
						  <a href="/file?name=%s">%s</a> %s
						  <form action="/delete" method="post" style="display:inline;" onsubmit="return confirm('确定要删除该文件吗？');">
							  <input type="hidden" name="path" value="%s">
							  <input type="hidden" name="dir" value="%s">
							  <input type="submit" value="删除" style="margin-left:10px;">
						  </form>
					  </li>
				  `, link, template.HTMLEscapeString(name), infoStr, template.HTMLEscapeString(relPath), template.HTMLEscapeString(rel))
		}
	}

	html += "</ul>"
	return html, nil
}
